JSON出力に対応したPostgreSQL 15のログをCloudWatch Logs Insightで検索する
2023/2/28についにRDS for PostgreSQLが正式にメジャーバージョンの15に対応しました。
Amazon RDS for PostgreSQL now supports major version PostgreSQL 15
正式リリースとのことPostgreSQL 15の追加機能を読み直していたのですが、
ログのフォーマットがjsonで出力できるようになっていました。
単体で読んでいる時はあまり気にしていなかったのですが、
RDSで取り扱うのであればCloudWatch Logsにお世話になる、
つまりCloudWatch Logs Insightとの相性が抜群では?と気づきました。
実際にどのような形で見ることができるのか気になったので試してみます。
RDS for PostgreSQLは現時点では未対応
さて記事のきっかけはPostgreSQL 15のRDSの正式対応となりますが、
残念なことに現時点ではパラメータグループのバリデーションを確認すると
log_destination
に対してjsonlog
の値が許可されていない状態となりました。
あくまで現時点で対応していないだけで将来的に対応される可能性はあると思いますので、
今回はそれを信じEC2上に立てたPostgreSQLのログを出力して確認します。
実行環境
- AlmaLinux release 9.1
- PostgreSQL 15.2
Amazon Linux 2のextrasには15がまだ入っていなかったのでAlmaLinuxで作業を行います。
IAMロール等の設定は省略します。
PostrgeSQLに必要な設定
今回対応したjson形式のでログを出力はlog_destination
の値をjsonlog
に設定することで対応できます。
またドキュメントに記載のあるとおりlogging_collector
をon
にする必要があるので注意しましょう。
https://www.postgresql.org/docs/15/runtime-config-logging.html#GUC-LOG-DESTINATION
If jsonlog is included in log_destination, log entries are output in JSON format, which is convenient for loading logs into programs. See Section 20.8.5 for details. logging_collector must be enabled to generate JSON-format log output.
PostgreSQLのセットアップ
インストールと初期化、ログ関連の設定の追加をします。
$ yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-9-x86_64/pgdg-redhat-repo-latest.noarch.rpm ... $ yum install -y postgresql15 postgresql15-server ... $ postgresql-15-setup initdb ... # ついでにログ関連は色々出るようにしておく $ cat <<EOS >> ~postgres/15/data/postgresql.conf log_destination=jsonlog logging_collector=on log_connections=on log_statement=all EOS $ service postgresql-15 start
ログはデフォルトでは以下の場所に配置されます。
$ ls -l ~postgres/15/data/log/ total 8 -rw-------. 1 postgres postgres 2317 Mar 6 11:29 postgresql-Mon.json -rw-------. 1 postgres postgres 169 Mar 6 11:29 postgresql-Mon.log
CloudWatch Logs エージェントのセットアップ
AlmaLinuxのデフォルトのリポジトリにはCloudWatch Logs エージェントは存在しないためS3上のパッケージよりインストールします。
$ yum install -y https://s3.ap-northeast-1.amazonaws.com/amazoncloudwatch-agent-ap-northeast-1/redhat/amd64/latest/amazon-cloudwatch-agent.rpm ... $ cat <<EOS > /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json { "agent": { "run_as_user": "postgres" }, "logs": { "logs_collected": { "files": { "collect_list": [ { "file_path": "/var/lib/pgsql/15/data/log/*.json", "log_group_name": "/local/{instance_id}", "log_stream_name": "postgresql.json", "retention_in_days": 3 } ] } } } } EOS $ service amazon-cloudwatch-agent start
この時点でCloudWatch Logs上にログが上がっていることを確認します。
ログ確認用にPostgreSQLに接続
セットアップアップのログも上がっているはずですが
念の為接続+クエリの実行でログを生成しておきます。
$ su - postgres ... $ psql psql (15.2) Type "help" for help. postgres=# postgres=# postgres=# SELECT version(); version ---------------------------------------------------------------------------------------------------------- PostgreSQL 15.2 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 11.3.1 20220421 (Red Hat 11.3.1-2), 64-bit (1 row)
stderrの場合のログ
JSON形式のログを見る前に
まずは一度一度標準のstderrで出力されるログを見てみましょう。
こちらは別途RDSで確認しようとした時に出力されたログですが、
プレーンテキスト形式のためCloudWatch Logs Insightで見ると特にフィールドが分かれず@message
から頑張って検索をかける必要があります。
jsonlogの場合のログ
JSONで出力されることにより各パラメータがフィールドごとに分かれており、
CloudWatch LogsやInsight上では見通しが良さそうです。
postgresユーザで接続しに行く前に誤ってrootユーザで接続しに行き、
認証に失敗していたのでそのログを探してみましょう。
fields @timestamp,error_severity, @message, @logStream, @log | filter error_severity = 'FATAL' | filter user = 'root' | sort @timestamp desc | limit 20
失敗しているログを抽出することができました。
ログの詳細としては以下のような出力となります。
今回特にrootユーザはクエリを流していないので省略しましたが、
実際はfilter ps = 'authentication'
もつけて探す方が良さそうです。
終わりに
さて今回はPostgreSQLのログをJSONで出力し、
CloudWatch Logs Insightで簡単に調査を行ってみました。
フィールド毎に検索をかけられるようになったことで、
これまで直感的にクエリをかけログを調査することができるようになったのではないかと思います。
サーバ上でgrepをかけて目で追えるレベルであればむしろJSONは見づらいかと思いますので、
ログ分析サービスを使っているような環境だからこそ嬉しいアップデートだと個人的には思っています。
※実際着色無しのJSONを見るのはかなり辛いと思います。
{"timestamp":"2023-03-06 12:14:18.828 UTC","pid":954,"session_id":"6405d7ee.3ba","line_num":1,"session_start":"2023-03-06 12:09:18 UTC","txid":0,"error_severity":"LOG","message":"checkpoint starting: time","backend_type":"checkpointer","query_id":0} {"timestamp":"2023-03-06 12:14:18.834 UTC","pid":954,"session_id":"6405d7ee.3ba","line_num":2,"session_start":"2023-03-06 12:09:18 UTC","txid":0,"error_severity":"LOG","message":"checkpoint complete: wrote 3 buffers (0.0%); 0 WAL file(s) added, 0 removed, 0 recycled; write=0.001 s, sync=0.002 s, total=0.006 s; sync files=2, longest=0.001 s, average=0.001 s; distance=0 kB, estimate=0 kB","backend_type":"checkpointer","query_id":0}
まさにRDSだからこそ必要とする機能なので対応してくれることを信じて祈っております。